﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

using DotNetNuke.Entities.Modules;

using DesertedRoadStudios.BlogNetNuke.Common;
using DesertedRoadStudios.BlogNetNuke.Components;

namespace DesertedRoadStudios.BlogNetNuke.UI.Widgets
{
    public class Archives : PortalModuleBase
    {
        public List<HierarchicalFormat> ArchiveHierachy { get { return _archiveHierachy; } }
        public List<Archive> ArchiveFullList { get { return _archiveFullList; } }

        private List<HierarchicalFormat> _archiveHierachy;
        private List<Archive> _archiveFullList;
        private XDocument _settings;
        private Dictionary<string, string> _widgetSettings;
        private IEnumerable<PostInfo> _posts;
        private bool _archivesShowPostCount;

        public class Archive
        {
            public string Date;
            public string ArchiveLink;
            public int Count = 0;
        }

        public class HierarchicalFormat
        {
            public string Year;
            public string YearLink;
            public List<Archive> Archives;
        }

        public Archives()
        {
        }
        
        public Archives(XDocument settings, Dictionary<string, string> widgetSettings, IEnumerable<PostInfo> posts)
        {
            _settings = settings;
            _widgetSettings = widgetSettings;
            _posts = posts;
        }

        protected void Page_Init(object sender, EventArgs e)
        {
            CheckWidget();
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (_widgetSettings["ArchiveFormat"].Equals("Hierarchical"))
                RenderHierarchical();
            else if (_widgetSettings["ArchiveFormat"].Equals("Full List"))
                RenderFullList();
            else
                throw new System.Exception("'Archive Format' unknown.");
        }

        private void CheckWidget()
        {
            if (!_widgetSettings["Widget"].Equals("Archives"))
                throw new System.Exception("Control doesn't implement DesertedRoadStudios.BlogNetNuke.UI.Widgets." + _widgetSettings["Widget"]);

            if (!_widgetSettings.ContainsKey("ArchiveFormat"))
            {
                throw new System.Exception("'Archive Format' unknown.");
            }

            if (!_widgetSettings.ContainsKey("ArchivesShowPostCount"))
                _archivesShowPostCount = false;
            else
                _archivesShowPostCount = Convert.ToBoolean(_widgetSettings["ArchivesShowPostCount"]);

        }

        private void RenderHierarchical()
        {
            _archiveHierachy = new List<HierarchicalFormat>();
            foreach (int date in _posts.Select(p => p.PublishedDate.Year).Distinct().OrderBy(p => p))
            {
                HierarchicalFormat hf = new HierarchicalFormat();
                hf.Year = date.ToString();
                hf.YearLink = Methods.GetPathExtension(_settings, _settings.Element("params").Element("Blog").Element("BlogDetails").Element("TabPath").Value.Replace("//", "/") + "/" + date.ToString());
                hf.Archives = new List<Archive>();

                foreach (string postDate in _posts.Where(p => p.PublishedDate.Year.Equals(date)).Select(p => p.PublishedDate.ToString("MMMM")).Distinct().OrderByDescending(p => p))
                {
                    Archive archive = new Archive();
                    archive.Date = postDate;
                    archive.ArchiveLink = Methods.GetPathExtension(_settings, _settings.Element("params").Element("Blog").Element("BlogDetails").Element("TabPath").Value.Replace("//", "/") + "/" + date.ToString() + "/" + _posts.Where(p => p.PublishedDate.Year.Equals(date) && p.PublishedDate.ToString("MMMM").Equals(postDate)).Select(p => p.PublishedDate.ToString("MM")).First());

                    if (_archivesShowPostCount)
                        archive.Count = _posts.Where(p => p.PublishedDate.Year.Equals(date) && p.PublishedDate.ToString("MMMM").Equals(postDate)).Count();

                    hf.Archives.Add(archive);
                }

                _archiveHierachy.Add(hf);
            }
        }

        private void RenderFullList()
        {
            _archiveFullList = new List<Archive>();
            
            foreach (int date in _posts.Select(p => p.PublishedDate.Year).Distinct().OrderBy(p => p))
            {
                foreach (string postDate in _posts.Where(p => p.PublishedDate.Year.Equals(date)).Select(p => p.PublishedDate.ToString("MMMM")).Distinct().OrderByDescending(p => p))
                {
                    Archive archive = new Archive();
                    archive.Date = postDate + " " + date.ToString();
                    archive.ArchiveLink = Methods.GetPathExtension(_settings, _settings.Element("params").Element("Blog").Element("BlogDetails").Element("TabPath").Value.Replace("//", "/") + "/" + date.ToString() + "/" + _posts.Where(p => p.PublishedDate.Year.Equals(date) && p.PublishedDate.ToString("MMMM").Equals(postDate)).Select(p => p.PublishedDate.ToString("MM")).First());

                    if (_archivesShowPostCount)
                        archive.Count = _posts.Where(p => p.PublishedDate.Year.Equals(date) && p.PublishedDate.ToString("MMMM").Equals(postDate)).Count();

                    _archiveFullList.Add(archive);
                }
            }
        }
    }
}